package com.wang.back.filter;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.wang.common.pojo.InfoEnum;
import com.wang.common.servlet.BaseServlet;
import com.wang.common.util.ConstatFinalUtil;
import com.wang.users.pojo.AAdmins;
import com.wang.users.pojo.AMenu;
import com.wang.users.pojo.ARoleMenu;
import com.wang.users.service.IAuthDbService;
import com.wang.users.service.IUsersDbService;
import com.wang.users.service.impl.AuthDbServiceImpl;
import com.wang.users.service.impl.UsersDbServiceImpl;

/**
 * 授权过滤器
 * @author Zjx
 *
 */
@WebFilter(urlPatterns = {"/back/*"})
public class Filter02Auth extends BaseServlet implements Filter
{
	private IAuthDbService authDbService = new AuthDbServiceImpl();
	private IUsersDbService usersDbService = new UsersDbServiceImpl();
	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException
	{
		System.out.println("===init===");
		/**
		 * instanceof 
		 */
		if(this.usersDbService instanceof UsersDbServiceImpl)
		{
			UsersDbServiceImpl usersDbServiceImpl = (UsersDbServiceImpl) usersDbService ; 
			usersDbServiceImpl.setAuthDbService(authDbService);
		}
		
		if(this.authDbService instanceof AuthDbServiceImpl)
		{
			AuthDbServiceImpl authDbServiceImpl = (AuthDbServiceImpl) authDbService ; 
			authDbServiceImpl.setUsersDbService(usersDbService);
		}
	}
	
	@Override
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
			throws IOException, ServletException
	{
		System.out.println("==AuthFilter==doFilter");
		HttpServletRequest request = (HttpServletRequest) req ; 
		HttpServletResponse response = (HttpServletResponse) resp ;
		
		HttpSession session = request.getSession();
		/* 验证用户是否登陆,因为只登陆才放了adminsSess */
		AAdmins adminsSess = (AAdmins) session.getAttribute("adminsSess");
		if(adminsSess == null)
		{
			this.info = ConstatFinalUtil.INFO_JSON.getString(InfoEnum.INFO_LOGIN_ILLEGAL.getCode() + "") ; 
			session.setAttribute("info", info);
			/* 肯定木有登陆 */
			this.clientRedirect(request, response, "/NoLoginBackServlet?method=login");
			/* 一定return; */
			return ; 
		}
		
		/* 判断单点登陆,根据上次登陆的ip判断
		 * session里面有一份信息
		 * 数据库里面也有一份信息
		 *  */
		/* 根据id查询数据库里面最新的信息 */
		Map<String,Object> condMap = new HashMap<String,Object>();
		condMap.clear();
		condMap.put("id", adminsSess.getId());
		AAdmins adminsDb = this.usersDbService.findOneAdminsService(condMap);
		if(!adminsDb.getLastLoginIp().equalsIgnoreCase(adminsSess.getLastLoginIp()))
		{
			/* 说明你的账号已经在其他地方登陆,强制下线 */
			this.info = ConstatFinalUtil.INFO_JSON.getString(InfoEnum.INFO_REMOTE_LOGIN.getCode() + "") ; 
			session.setAttribute("info", info);
			session.removeAttribute("lastLoginTime");
			session.removeAttribute("adminsSess");
			this.clientRedirect(request, response, "/NoLoginBackServlet?method=login");
			return ; 
		}
		
		/* 验证权限 */
		boolean flag = verifyAuth(request,response,adminsDb);
		
		if(flag)
		{
			/* 放行 */
			chain.doFilter(request, response);
		}else
		{
			/* 木有权限 */
			this.serverRedirect(request, response, "/back/noAuth");
		}
	}

	/**
	 * 如何验证当前这个用户访问这个链接是否有权限呢?
	 * 	用户和角色有关系;用户和菜单木有关系;一个用户只能有一个角色
	 * 	查询出这个角色下面所有的菜单;
	 * 	如何知道当前页面访问的是哪个菜单呢?
	 * @param request
	 * @param response
	 * @return
	 */
	private boolean verifyAuth(HttpServletRequest request, HttpServletResponse response,AAdmins admins)
	{
		if(admins.getId() == 1)
		{
			return true ; 
		}
		
		/* 获取当前访问的url */
		String url = request.getRequestURL() + "";
		String queryStr = request.getQueryString() ; 
		if(queryStr != null)
		{
			url = url + "?" + queryStr ; 
		}
		System.out.println("==url==" + url);
		
		/* 查询当前管理员角色有哪些菜单 */
		Map<String,Object> condMap = new HashMap<String, Object>();
		
		condMap.clear();
		condMap.put("roleId", admins.getRoleId());
		condMap.put("extend", "true");
		List<ARoleMenu> roleMenuList = this.authDbService.findCondListRoleMenuService(null, condMap);
		for (ARoleMenu roleMenu : roleMenuList)
		{
			AMenu menuTemp = roleMenu.getMenu() ; 
			/* 因为menu里面有url;我们定义url的时候就是取自地址栏中的一部分 */
			if(url.indexOf(menuTemp.getUrl()) != -1)
			{
				/* 用户访问的url包含数据库中菜单的url;说明有权限 */
				return true ; 
			}
		}
		return false;
	}

}
